#include <stdio.h>

typedef enum {
    OP_PUSH,
    OP_POP,
    OP_MOV,
    OP_ADD,
    OP_SUB,
    OP_MUL,
    OP_DIV,
    OP_MOD,
    OP_CMP,
    OP_JMP,
    OP_JE,
    OP_JNE,
    OP_JL,
    OP_JG,
    OP_JLE,
    OP_JGE,
    OP_JZ,
    OP_JNZ,
    OP_CALL,
    OP_RET,
    OP_NOP,
    OP_IN,
    OP_OUT,
    OP_HLT,
} OpCode;

typedef enum {
    EAX,
    EBX,
    ECX,
    EDX,
    EBP,
    EDI,
    ESI,
    ESP,
} RegType;

typedef enum {
    REG,
    NUM,
    MEM,
} OperandType;

int command[] = {
    OP_MOV, REG, EAX, NUM, 'H',             // mov eax, 'H'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'e',             // mov eax, 'e'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'l',             // mov eax, 'l'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'o',             // mov eax, 'o'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, ',',             // mov eax, ','
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, ' ',             // mov eax, ' '
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'W',             // mov eax, 'W'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'o',             // mov eax, 'o'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'r',             // mov eax, 'r'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'l',             // mov eax, 'l'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, 'd',             // mov eax, 'd'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_MOV, REG, EAX, NUM, '!',             // mov eax, '!'
    OP_OUT, NUM, 1, EAX,                    // out 1, eax
    OP_HLT                                  // hlt
};

int main(int argc, char **argv)
{
	if (argc == 1 || argc > 2) {
		printf("Usage: %s code.bin", argv[0]);
		return 0;
	}
	
	char *filename = argv[1];
	FILE *f = fopen(filename, "wb");
	fwrite(command, sizeof(int), sizeof(command) / sizeof(int), f);
	return 0;
}